﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using centraldba_library.Data;

namespace centraldba_dbrestore_utility
{
    /// <summary>
    /// Interaction logic for frmStatusWindow.xaml
    /// </summary>
    public partial class frmStatusWindow : Window
    {
        recovery_manager rman;
        string _destinationInstance;

        public frmStatusWindow()
        {
            InitializeComponent();

            // Initialize the interface to data
            rman = new recovery_manager(centraldba_dbrestore_utility.Properties.Settings.Default.ConnectionStringTemplate,
                                        centraldba_dbrestore_utility.Properties.Settings.Default.centraldba_server_name,
                                        centraldba_dbrestore_utility.Properties.Settings.Default.centraldba_db_name);
            rman.InfoMessage += new System.Data.SqlClient.SqlInfoMessageEventHandler(rman_InfoMessage);
            rman.Error += rman_Error;
        }

        #region Events
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            ResizePopupWindow();
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ResizePopupWindow();
        }

        private void cmdClose_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void PopupClose_Click(object sender, RoutedEventArgs e)
        {
            wndResults.Close();
        }

        private void OnResultsClicked(object sender, RoutedEventArgs e)
        {
            wndResults.Show();
        }

        private void rman_Error(object sender, EventArgs e)
        {
            if (e != null)
            {
                // Update the status of the job step
                foreach (restore_script mrs in dataGrid1.Items)
                {
                    if (mrs.Processing)
                    {
                        // Add result message
                        mrs.Result += ((RecoveryManagerEventArgs)e).Message;

                        // Exit for loop
                        break;
                    }
                }
            }
        }

        void rman_InfoMessage(object sender, System.Data.SqlClient.SqlInfoMessageEventArgs e)
        {
            Dispatcher.BeginInvoke((Action)delegate
            {
                // Declare Local Variables
                StringBuilder msg = new StringBuilder();
                bool job_failed = false;

                // Get the message(s)
                if (e.Errors.Count > 0)
                {
                    foreach (System.Data.SqlClient.SqlError er in e.Errors)
                    {
                        // Add the message
                        msg.AppendLine(er.Message);

                        // Determine if this is a job failure
                        if (er.Class > 10)
                            job_failed = true;
                    }
                }
                else
                    msg.AppendLine(e.Message);

                // Update the status of the job step
                foreach (restore_script mrs in dataGrid1.Items)
                {
                    if (mrs.Processing)
                    {
                        // Set status
                        mrs.Succeeded = !job_failed;

                        // Add result message
                        mrs.Result += msg.ToString();

                        // Exit for loop
                        break;
                    }
                }

                // Cleanup
                msg.Clear();
            });
        }

        #endregion

        #region Methods

        private void ResizePopupWindow()
        {
            wndResults.Width = this.Width - 50;
            wndResults.Height = this.Height - 50;
        }

        public async void RestoreDatabase(string sourceInstance, string destinationInstance, string sourceDatabase, string destinationDatabase, string restoreLabel, Int32 backup_set_id, string stopat_time)
        {
            // Pre-process parameters
            sourceInstance = sourceInstance.Trim();
            destinationInstance = destinationInstance.Trim();
            sourceDatabase = sourceDatabase.Trim();
            destinationDatabase = destinationDatabase.Trim();
            restoreLabel = restoreLabel.Trim();
            stopat_time = stopat_time.Trim();

            // Remove any previous binding
            dataGrid1.ItemsSource = null;
            _destinationInstance = destinationInstance;

            // Declare Local Variables
            Collection<restore_script> restoreScripts;

            // Get the restore script
            restoreScripts = rman.GetRestoreScripts(sourceInstance, sourceDatabase, destinationDatabase, restoreLabel, backup_set_id, stopat_time);

            // Setup the status display
            dataGrid1.ItemsSource = restoreScripts;

            // Execute the commands
            foreach (restore_script mrs in dataGrid1.Items)
            {
                // Scroll the DataGrid so this current record is in view
                dataGrid1.ScrollIntoView(mrs);

                // Execute the first command
                mrs.Started = true;
                mrs.Processing = true;
                mrs.Succeeded = await rman.ExecuteQuery(destinationInstance, mrs.Command);
                mrs.Processing = false;
            }
            MessageBox.Show("Restore Operation Complete.", "Database Restore");
        }

        #endregion
    }
}
